<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>山芋头</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="记录和总结让知识得到积累，分享能创造价值">
<meta property="og:type" content="website">
<meta property="og:title" content="山芋头">
<meta property="og:url" content="https://bianchengme.gitee.io/page/4/index.html">
<meta property="og:site_name" content="山芋头">
<meta property="og:description" content="记录和总结让知识得到积累，分享能创造价值">
<meta property="og:locale" content="cn">
<meta property="article:author" content="jmme@foxmail.com">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="山芋头" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">

<meta name="generator" content="Hexo 4.2.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">山芋头</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">记录和分享能创造价值</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://bianchengme.gitee.io"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-git-常用命令" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/25/git-%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/" class="article-date">
  <time datetime="2020-04-25T01:34:59.000Z" itemprop="datePublished">2020-04-25</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/git/">git</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/25/git-%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/">git 常用命令</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>提交git commit 的时候，发现一个文件无法被gitinore，猜测可能是已经提交过或者已经在git缓存里了，只有删除追踪和缓存才能被忽略。</p>
<p>1、先尝试取消git追踪文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git update-index –assume-unchanged readme1.txt &#x2F;&#x2F;清除该文件的是索引</span><br></pre></td></tr></table></figure>

<ul>
<li>本地的当前分支取消了追踪</li>
<li>本文文件不删除， 远程仓库仍是存在此文件。</li>
<li>本次clone的所有分支都不追踪此文件。</li>
<li>重新git clone后此文件仍是会被追踪。</li>
<li>但是不能彻底消除追踪文件，因为可能本地git缓存中有该文件。</li>
</ul>
<p>2、删除git的缓存</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rm --cached readme1.txt &#x2F;&#x2F;删除readme1.txt的git的缓存，并保留本地文件。</span><br></pre></td></tr></table></figure>

<ul>
<li>如果想本地缓存和文件一起删除 <code>git rm --f readme1.txt</code></li>
</ul>
<p>这时候再次 <code>git status</code>看看应该就不显示 readme1.txt了。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/25/git-%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/" data-id="cktcaskhm001z3guch9dwa1qc" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/git/" rel="tag">git</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-Cocoapods-CDN-错误" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/24/Cocoapods-CDN-%E9%94%99%E8%AF%AF/" class="article-date">
  <time datetime="2020-04-24T07:48:35.000Z" itemprop="datePublished">2020-04-24</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/iOS/">iOS</a>►<a class="article-category-link" href="/categories/iOS/Xcode/">Xcode</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/24/Cocoapods-CDN-%E9%94%99%E8%AF%AF/">Cocoapods CDN 错误</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>最近Cocoapods升级到1.8.4后，install和update都没有问题，但是search的时候就遇到了问题，问题如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CDN: trunk URL couldn&#39;t be downloaded: https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;CocoaPods&#x2F;Specs&#x2F;master&#x2F;Specs&#x2F;0&#x2F;a&#x2F;8&#x2F;YYModel@Haidora&#x2F;1.0.4&#x2F;YYModel@Haidora.podspec.json, </span><br><span class="line">error: Failed to open TCP connection to raw.githubusercontent.com:443 (Connection refused - connect(2) for &quot;raw.githubusercontent.com&quot; port 443)</span><br></pre></td></tr></table></figure>

<p>解决办法比较简单，<strong>在Podfile中添加source</strong>：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">source &#39;https:&#x2F;&#x2F;github.com&#x2F;CocoaPods&#x2F;Specs.git&#39;</span><br><span class="line"></span><br><span class="line">target &#39;XXXDemo&#39; do</span><br><span class="line"></span><br><span class="line">  use_frameworks!</span><br><span class="line"></span><br><span class="line">  pod &#39;YYModel&#39;</span><br><span class="line"></span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p><strong>移除trunk</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pod repo remove trunk</span><br></pre></td></tr></table></figure>

<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>为什么这样呢，很明显CDN的错误，这个问题如何解决呢，改日再找找…</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/24/Cocoapods-CDN-%E9%94%99%E8%AF%AF/" data-id="cktcaskh7000p3gucdv1bce7g" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Xcode/" rel="tag">Xcode</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/iOS/" rel="tag">iOS</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-Objective-C之NS-ASSUME-NONNULL-BEGIN-NS-ASSUME-NONNULL-END" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/24/Objective-C%E4%B9%8BNS-ASSUME-NONNULL-BEGIN-NS-ASSUME-NONNULL-END/" class="article-date">
  <time datetime="2020-04-24T07:46:31.000Z" itemprop="datePublished">2020-04-24</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/iOS/">iOS</a>►<a class="article-category-link" href="/categories/iOS/Objective-C/">Objective-C</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/24/Objective-C%E4%B9%8BNS-ASSUME-NONNULL-BEGIN-NS-ASSUME-NONNULL-END/">Objective-C之NS_ASSUME_NONNULL_BEGIN &amp; NS_ASSUME_NONNULL_END</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="NS-ASSUME-NONNULL-BEGIN-amp-amp-NS-ASSUME-NONNULL-END"><a href="#NS-ASSUME-NONNULL-BEGIN-amp-amp-NS-ASSUME-NONNULL-END" class="headerlink" title="NS_ASSUME_NONNULL_BEGIN &amp;&amp; NS_ASSUME_NONNULL_END"></a>NS_ASSUME_NONNULL_BEGIN &amp;&amp; NS_ASSUME_NONNULL_END</h1><p>在Swift中存在Option类型，也就是使用？和！声明的变量。但是OC里面没有这个特征,因为在XCODE6.3之后出现新的关键词定义用于OC转SWIFT时候可以区分到底是什么类型</p>
<p><strong>nullable &amp;&amp; _</strong>nonnull<br>__nullable指代对象可以为NULL或者为NIL<br>__nonnull指代对象不能为null<br>当我们不遵循这一规则时，编译器就会给出警告。</p>
<p>我们来看看以下的实例，</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">@interface TestNullabilityClass ()</span><br><span class="line">@property (nonatomic, copy) NSArray * items;</span><br><span class="line">- (id)itemWithName:(NSString * __nonnull)name;</span><br><span class="line">@end</span><br><span class="line">@implementation TestNullabilityClass</span><br><span class="line">...</span><br><span class="line">- (void)testNullability &#123;</span><br><span class="line">    [self itemWithName:nil];    &#x2F;&#x2F; 编译器警告：Null passed to a callee that requires a non-null argument</span><br><span class="line">&#125;</span><br><span class="line">- (id)itemWithName:(NSString * __nonnull)name &#123;</span><br><span class="line">    return nil;</span><br><span class="line">&#125;</span><br><span class="line">@end</span><br></pre></td></tr></table></figure>

<p>事实上，在任何可以使用<code>const</code>关键字的地方都可以使用<code>__nullable</code>和<code>__nonnull</code>，不过这两个关键字仅限于使用在指针类型上。而在方法的声明中，我们还可以使用不带下划线的<code>nullable</code>和<code>nonnull</code>，如下所示：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">- (nullable id)itemWithName:(NSString * nonnull)name</span><br></pre></td></tr></table></figure>

<p>在属性声明中，也增加了两个相应的特性，因此上例中的items属性可以如下声明：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@property (nonatomic, copy, nonnull) NSArray * items;</span><br></pre></td></tr></table></figure>

<p>当然也可以用以下这种方式：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@property (nonatomic, copy) NSArray * __nonnull items;</span><br></pre></td></tr></table></figure>

<p>推荐使用<code>nonnul</code>l这种方式，这样可以让属性声明看起来更清晰。</p>
<p><code>Non null</code>区域设置(Audited Regions)</p>
<p>如果需要每个属性或每个方法都去指定<code>nonnull</code>和<code>nullable</code>，是一件非常繁琐的事。苹果为了减轻我们的工作量，专门提供了两个宏：<code>NS_ASSUME_NONNULL_BEGIN</code>和<code>NS_ASSUME_NONNULL_END</code>。在这两个宏之间的代码，所有简单指针对象都被假定为nonnull，因此我们只需要去指定那些nullable的指针。如下代码所示：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">NS_ASSUME_NONNULL_BEGIN</span><br><span class="line">@interface TestNullabilityClass ()</span><br><span class="line">@property (nonatomic, copy) NSArray * items;</span><br><span class="line">- (id)itemWithName:(nullable NSString *)name;</span><br><span class="line">@end</span><br><span class="line">NS_ASSUME_NONNULL_END</span><br></pre></td></tr></table></figure>

<p>在上面的代码中，items属性默认是<code>non null</code>的，itemWithName:方法的返回值也是<code>non null</code>，而参数是指定为<code>nullable</code>的。</p>
<p>不过，为了安全起见，苹果还制定了几条规则：</p>
<p>typedef定义的类型的nullability特性通常依赖于上下文，即使是在Audited Regions中，也不能假定它为<code>nonnulla</code>。<br> 复杂的指针类型(如id *)必须显示去指定是<code>nonnull</code>还是<code>nullable</code>。例如，指定一个指向<code>nullable</code>对象的<code>nonnull</code>指针，可以使用</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">__nullable id * __nonnull</span><br></pre></td></tr></table></figure>

<p>我们经常使用的<code>NSError **</code>通常是被假定为一个指向<code>nullable NSError</code>对象的nullable指针。<br> 兼容性</p>
<p>因为Nullability Annotations是Xcode 6.3新加入的，所以我们需要考虑之前的老代码。实际上，苹果已以帮我们处理好了这种兼容问题，我们可以安全地使用它们：</p>
<p>老代码仍然能正常工作， 即使对<code>nonnull</code>对象使用了nil也没有问题。<br> 老代码在需要和swift混编时，在新的swift编译器下会给出一个警告。<br> <code>nonnull</code>不会影响性能。事实上，我们仍然可以在运行时去判断我们的对象是否为<code>nil</code>。<br> 事实上，我们可以将<code>nonnull/nullable</code>与我们的断言和异常一起看待，其需要处理的问题都是同一个：违反约定是一个程序员的错误。特别是，返回值是我们可控的东西，如果返回值是<code>nonnull</code>的，则我们不应该返回<code>nil</code>，除非是为了向后兼容。</p>
<h1 id="NS-ENUM-AVAILABLE-IOS"><a href="#NS-ENUM-AVAILABLE-IOS" class="headerlink" title="NS_ENUM_AVAILABLE_IOS"></a>NS_ENUM_AVAILABLE_IOS</h1><p>从单词的字面可以看出使用这个宏说明这个枚举开始IOS的版本</p>
<blockquote>
<p>IOS版本如下 7_0 代表7.0的版本.用_替换<br> 参数只有一个NS_ENUM_AVAILABLE_IOS(2_0) 代表&gt;=2.0开始</p>
</blockquote>
<h1 id="NS-ENUM-DEPRECATED-IOS"><a href="#NS-ENUM-DEPRECATED-IOS" class="headerlink" title="NS_ENUM_DEPRECATED_IOS"></a>NS_ENUM_DEPRECATED_IOS</h1><p>代表枚举类型已经过时的API 第一个参数是开始的时候，第二个参数是过时的时候</p>
<blockquote>
<p>NS_ENUM_DEPRECATED_IOS(2_0,7_0) 代表开始于IOS2.0废弃于IOS7.0 也就是&gt;=2.0 &lt;=7.0</p>
</blockquote>
<h1 id="TVOS-PROHIBITED"><a href="#TVOS-PROHIBITED" class="headerlink" title="__TVOS_PROHIBITED"></a>__TVOS_PROHIBITED</h1><blockquote>
<p>代表这个枚举或者类，方法，参数在TVOS系统上面不能使用</p>
</blockquote>
<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="built_in">NS_ENUM</span>(<span class="built_in">NSInteger</span>, <span class="built_in">UIStatusBarStyle</span>) &#123;</span><br><span class="line">    <span class="built_in">UIStatusBarStyleDefault</span>                                     = <span class="number">0</span>, <span class="comment">// Dark content, for use on light backgrounds</span></span><br><span class="line">    <span class="built_in">UIStatusBarStyleLightContent</span>     <span class="built_in">NS_ENUM_AVAILABLE_IOS</span>(<span class="number">7</span>_0) = <span class="number">1</span>, <span class="comment">// Light content, for use on dark backgrounds</span></span><br><span class="line"></span><br><span class="line">    <span class="built_in">UIStatusBarStyleBlackTranslucent</span> <span class="built_in">NS_ENUM_DEPRECATED_IOS</span>(<span class="number">2</span>_0, <span class="number">7</span>_0, <span class="string">"Use UIStatusBarStyleLightContent"</span>) = <span class="number">1</span>,</span><br><span class="line">    <span class="built_in">UIStatusBarStyleBlackOpaque</span>      <span class="built_in">NS_ENUM_DEPRECATED_IOS</span>(<span class="number">2</span>_0, <span class="number">7</span>_0, <span class="string">"Use UIStatusBarStyleLightContent"</span>) = <span class="number">2</span>,</span><br><span class="line">&#125; __TVOS_PROHIBITED;</span><br></pre></td></tr></table></figure>

<h1 id="UIKIT-EXTERN"><a href="#UIKIT-EXTERN" class="headerlink" title="UIKIT_EXTERN"></a>UIKIT_EXTERN</h1><blockquote>
<p><code>extern</code>这个是定义字符串 变量 比<code>#define</code>更加的高效 .但是UIKIT_EXTERN是根据是否是C语言宏定义，根据语言区分 ，比extern更加的高效</p>
</blockquote>
<h6 id="例子"><a href="#例子" class="headerlink" title="例子"></a>例子</h6><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">UIKIT_EXTERN</span> <span class="built_in">NSString</span> *<span class="keyword">const</span> <span class="built_in">UIApplicationInvalidInterfaceOrientationException</span> <span class="built_in">NS_AVAILABLE_IOS</span>(<span class="number">6</span>_0) __TVOS_PROHIBITED;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>上面的代码一般定义在.H 在.M实现 实现要去掉UIKIT_EXTERN.代表IOS6.0之后可以用，在TVOS系统不可用。</p>
</blockquote>
<h1 id="NS-CLASS-AVAILABLE-IOS"><a href="#NS-CLASS-AVAILABLE-IOS" class="headerlink" title="NS_CLASS_AVAILABLE_IOS"></a>NS_CLASS_AVAILABLE_IOS</h1><blockquote>
<p>代表类开始的API 和上面说的类似</p>
</blockquote>
<h6 id="例子-1"><a href="#例子-1" class="headerlink" title="例子"></a>例子</h6><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">NS_CLASS_AVAILABLE_IOS</span>(<span class="number">2</span>_0) <span class="class"><span class="keyword">@interface</span> <span class="title">UIApplication</span> : <span class="title">UIResponder</span></span></span><br></pre></td></tr></table></figure>

<h1 id="NS-EXTENSION-UNAVAILABLE-IOS"><a href="#NS-EXTENSION-UNAVAILABLE-IOS" class="headerlink" title="NS_EXTENSION_UNAVAILABLE_IOS"></a>NS_EXTENSION_UNAVAILABLE_IOS</h1><blockquote>
<p>标记IOS插件不能使用这些API,后面有一个参数，可以作为提示，用什么API替换</p>
</blockquote>
<h6 id="例子-2"><a href="#例子-2" class="headerlink" title="例子"></a>例子</h6><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">+ (<span class="built_in">UIApplication</span> *)sharedApplication <span class="built_in">NS_EXTENSION_UNAVAILABLE_IOS</span>(<span class="string">"Use view controller based solutions where appropriate instead."</span>);</span><br></pre></td></tr></table></figure>

<h1 id="kindof"><a href="#kindof" class="headerlink" title="__kindof"></a>__kindof</h1><blockquote>
<p>可以参考下面的连接 我就不多啰嗦了</p>
</blockquote>
<p><a href="https://link.jianshu.com?t=http://blog.csdn.net/leikezhu1981/article/details/47418011" target="_blank" rel="noopener">Xcode 7新的特性Lightweight Generics 轻量级泛型与__kindof修饰符</a></p>
<h1 id="NS-REQUIRES-SUPER"><a href="#NS-REQUIRES-SUPER" class="headerlink" title="NS_REQUIRES_SUPER"></a>NS_REQUIRES_SUPER</h1><blockquote>
<p>字面上必须继承父类的方法(有待考证)</p>
</blockquote>
<h1 id="SDK-HIDE-TIDE"><a href="#SDK-HIDE-TIDE" class="headerlink" title="SDK_HIDE_TIDE"></a>SDK_HIDE_TIDE</h1><blockquote>
<p>暂定 没查到干什么的 字面上是在SDK隐藏</p>
</blockquote>
<h1 id="NS-DESIGNATED-INITIALIZER"><a href="#NS-DESIGNATED-INITIALIZER" class="headerlink" title="NS_DESIGNATED_INITIALIZER"></a>NS_DESIGNATED_INITIALIZER</h1><blockquote>
<p>用来定义一些初始化方法只能过来这些标记的初始化</p>
</blockquote>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/24/Objective-C%E4%B9%8BNS-ASSUME-NONNULL-BEGIN-NS-ASSUME-NONNULL-END/" data-id="cktcaskhj001r3guc0sqf5y36" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Objective-C/" rel="tag">Objective-C</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/iOS/" rel="tag">iOS</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-用clang编译Objective-C对象，理解运行时机制" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/19/%E7%94%A8clang%E7%BC%96%E8%AF%91Objective-C%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%90%86%E8%A7%A3%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9C%BA%E5%88%B6/" class="article-date">
  <time datetime="2020-04-19T03:26:59.000Z" itemprop="datePublished">2020-04-19</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/iOS/">iOS</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/19/%E7%94%A8clang%E7%BC%96%E8%AF%91Objective-C%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%90%86%E8%A7%A3%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9C%BA%E5%88%B6/">用clang编译Objective-C对象，理解运行时机制</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>我们知道<code>Objective-C</code>的类可以通过<code>clang</code>编译器转换为<code>C++</code>的结构体，也就是说，<code>Objective-C</code>对象的本质就是结构体，下面通过实践来证明。</p>
<p>创建一个命令行项目（<a href="https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fnchkdxlq%2FClassDemo" target="_blank" rel="noopener">这里</a>可以找到），在main.m文件添加如下的代码</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">#import &lt;Foundation&#x2F;Foundation.h&gt;</span><br><span class="line">@interface Person: NSObject &#123;</span><br><span class="line">    int _age;</span><br><span class="line">    double _height;</span><br><span class="line">&#125;</span><br><span class="line">@end</span><br><span class="line"></span><br><span class="line">@implementation Person</span><br><span class="line">@end</span><br><span class="line"></span><br><span class="line">int main(int argc, const char * argv[]) &#123;</span><br><span class="line">    @autoreleasepool &#123;</span><br><span class="line">        &#x2F;&#x2F; insert code here...</span><br><span class="line">        NSLog(@&quot;Hello, World!&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">    return 0;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后使用<code>clang</code>编译器重写<code>main.m</code>文件，可指定平台iOS和架构arm64，在main.m所在的文件夹执行如下命令</p>
<p><code>xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp</code> </p>
<p>会得到一个main-arm64.cpp的文件，可看到<code>Person</code>类转换为<code>struct Person_IMPL</code>结构体</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Person_IMPL</span> &#123;</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">NSObject_IMPL</span> <span class="title">NSObject_IVARS</span>;</span></span><br><span class="line">    <span class="keyword">int</span> _age;</span><br><span class="line">    <span class="keyword">double</span> _height;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>存在上面定义<code>Person</code>类时声明的<code>_age</code>和<code>_height</code>成员变量，发现第一个成员变量是<code>struct NSObject_IMPL</code>结构体，这是<code>NSObject</code>被<code>clang</code>编译器重写后对应的结构体，在<code>main-arm64.cpp</code>文件中可找到声明</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">NSObject_IMPL</span> &#123;</span></span><br><span class="line">    Class isa;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="实例对象（instance）"><a href="#实例对象（instance）" class="headerlink" title="实例对象（instance）"></a>实例对象（instance）</h2><p><code>Objictive-C</code><strong>实例对象</strong>是通过<strong>类对象</strong>创建</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Person *p1 = [Person <span class="keyword">new</span>];</span><br><span class="line">Person *p2 = [[Person alloc] init];</span><br></pre></td></tr></table></figure>

<p><strong>实例对象</strong>分配在<strong>堆空间</strong>，所以<strong>p1、p2</strong>指向的内存地址都在<strong>堆</strong>上；每次创建的都是不同的对象，所以在内存中会存在很多个实例对象。</p>
<p>把<code>struct NSObject_IMPL</code>与<code>struct Person_IMPL</code>合并一下得到下面的结构</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Person_IMPL</span> &#123;</span></span><br><span class="line">    Class isa;</span><br><span class="line">    <span class="keyword">int</span> _age;</span><br><span class="line">    <span class="keyword">double</span> _height;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>这也是<code>Person</code>实例对象在内存中的布局情况。</p>
<p>总结一下实例对象中包含信息</p>
<ul>
<li><strong>isa</strong>指针，指向类对象</li>
<li>成员变量，其实<strong>isa</strong>也是成员变量，只不过比较特殊，它指向这个实例对象的类对象。</li>
</ul>
<h2 id="类对象（class）"><a href="#类对象（class）" class="headerlink" title="类对象（class）"></a>类对象（class）</h2><p>类对象是对实例对象的描述，描述这个类实例对象有哪些成员变量、属性、对象方法、类方法，那这些信息存储在什么地方呢？（下面提及的数据类型<a href="https://link.jianshu.com?t=https%3A%2F%2Fgithub.com%2Fnchkdxlq%2Fobjc-runtime%2Ftree%2Fmaster%2Fruntime" target="_blank" rel="noopener">这里</a>可以找到）</p>
<p>类对象声明为<code>typedef struct objc_class *Class;</code>，再看看<code>struct objc_class</code>结构体，截取一些关键的信息看看</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">objc_class</span> :</span> objc_object &#123;</span><br><span class="line">    <span class="comment">// Class ISA;</span></span><br><span class="line">    Class superclass;</span><br><span class="line">    <span class="keyword">cache_t</span> cache;             <span class="comment">// formerly cache pointer and vtable</span></span><br><span class="line">    <span class="keyword">class_data_bits_t</span> bits;    <span class="comment">// class_rw_t * plus custom rr/alloc flags</span></span><br><span class="line">    <span class="function"><span class="keyword">class_rw_t</span> *<span class="title">data</span><span class="params">()</span> </span>&#123; </span><br><span class="line">        <span class="keyword">return</span> bits.data();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// ... 还有很多方法，略去</span></span><br><span class="line">&#125;；</span><br></pre></td></tr></table></figure>

<p><code>superclass</code>指向父类，其他的信息存储在<code>class_rw_t</code>的结构体中，定义如下</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">class_rw_t</span> &#123;</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">class_ro_t</span> *ro; <span class="comment">// 实例变量信息</span></span><br><span class="line">    <span class="keyword">method_array_t</span> methods; <span class="comment">// 对象方法信息</span></span><br><span class="line">    <span class="keyword">property_array_t</span> properties; <span class="comment">// 属性信息</span></span><br><span class="line">    <span class="keyword">protocol_array_t</span> protocols; <span class="comment">// 协议信息</span></span><br><span class="line">     <span class="comment">// ... 省略其他信息</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>runtime</code>提供这些信息函数如下</p>
<p>获取实例变量</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Ivar *</span><br><span class="line">class_copyIvarList(Class cls, <span class="keyword">unsigned</span> <span class="keyword">int</span> *outCount)</span><br></pre></td></tr></table></figure>

<p>获取属性信息</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">objc_property_t</span> * </span><br><span class="line">class_copyPropertyList(Class cls, <span class="keyword">unsigned</span> <span class="keyword">int</span> *outCount)</span><br></pre></td></tr></table></figure>

<p>获取对象方法</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 第一个参数是 *类对象*，返回的是*对象方法*；如果是参数*元类对象*，返回的是*对象方法*</span></span><br><span class="line">Method *</span><br><span class="line">class_copyMethodList(Class cls, <span class="keyword">unsigned</span> <span class="keyword">int</span> *outCount)</span><br></pre></td></tr></table></figure>

<p>获取协议信息</p>
<figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Protocol * __<span class="keyword">unsafe_unretained</span> * </span><br><span class="line">class_copyProtocolList(Class cls, <span class="keyword">unsigned</span> <span class="keyword">int</span> *outCount)</span><br></pre></td></tr></table></figure>

<p><code>struct objc_class</code>继承<code>objc_object</code>，<code>struct objc_object</code>结构如下</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">objc_object</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">isa_t</span> isa;</span><br><span class="line">    <span class="comment">// ...省略方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>那<code>isa_t</code>是联合体，结构如下</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">union</span> <span class="keyword">isa_t</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">isa_t</span>() &#123; &#125;</span><br><span class="line">    <span class="keyword">isa_t</span>(<span class="keyword">uintptr_t</span> value) : bits(value) &#123; &#125;</span><br><span class="line">    Class cls;</span><br><span class="line">    <span class="keyword">uintptr_t</span> bits;</span><br><span class="line">     <span class="comment">// ...省略</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这里面有个 <code>cls</code>成员，这个就是<code>class</code>指向<code>mata-class</code>的指针。</p>
<p>总结一下<strong>类对象（class）</strong>中存储的信息</p>
<ul>
<li><strong>isa</strong>指针，指向<strong>元类</strong>的指针</li>
<li><strong>superclass</strong>指向<strong>父类</strong>的指针</li>
<li><strong>成员变量（Ivar）</strong>的描述信息</li>
<li><strong>属性（property）</strong>的描述信息</li>
<li><strong>对象方法（Instance Method）</strong>的描述信息</li>
<li><strong>遵循协议（protocol）</strong>的描述信息</li>
</ul>
<h2 id="元类对象（meta-class）"><a href="#元类对象（meta-class）" class="headerlink" title="元类对象（meta-class）"></a>元类对象（meta-class）</h2><p>上面可以看出，<strong>meta-class</strong>也是一个<strong>Class \</strong>类型，与*<em>类对象*</em>的数据类型时一样的，只不过存储的信息不同。<br> <strong>元类对象（meta-class）</strong>存储的信息有</p>
<ul>
<li><strong>isa</strong>指针，指向基类（NSObject）<strong>元类（meta-class）</strong>的指针，所有<strong>元类（meta-class）</strong>的<strong>isa</strong>指针都指向<strong>NSObject</strong>元类的指针。</li>
<li><strong>superclass</strong>指向父类的<strong>元类（meta-class）</strong>的指针</li>
<li><strong>类方法（class Method）</strong>的描述信息</li>
</ul>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>上面讲了<strong>实例对象</strong>的内存布局，以及<strong>实例对象（instance）</strong>、<strong>类对象（class）</strong>、<strong>元类对象（meta-class）</strong>之间的关系，最后用一张图来说明它们之间的关系。</p>
<p><img src="/Users/guagua/program/hexo/xinghaizi/source/_posts/%E7%94%A8clang%E7%BC%96%E8%AF%91Objective-C%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%90%86%E8%A7%A3%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9C%BA%E5%88%B6/01.png" alt=""></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/19/%E7%94%A8clang%E7%BC%96%E8%AF%91Objective-C%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%90%86%E8%A7%A3%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9C%BA%E5%88%B6/" data-id="cktcaskit005o3guca3ncd6fu" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Objective-C/" rel="tag">Objective-C</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/iOS/" rel="tag">iOS</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-npm-ERR-code-EINTEGRITY" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/14/npm-ERR-code-EINTEGRITY/" class="article-date">
  <time datetime="2020-04-14T10:15:45.000Z" itemprop="datePublished">2020-04-14</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/14/npm-ERR-code-EINTEGRITY/">npm ERR! code EINTEGRITY</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>在用npm安装bower <code>sudo npm install -g bower</code> 报错 <code>npm ERR! code EINTEGRITY</code> 产生的原因似乎是node源的问题，下面是我解决问题的过程。</p>
<ol>
<li><p>切换为淘宝的源</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm config set registry https:&#x2F;&#x2F;registry.npm.taobao.org</span><br><span class="line">npm info underscore</span><br></pre></td></tr></table></figure>
</li>
<li><p>清理缓存</p>
</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm cache verify</span><br><span class="line">npm cache clean --force</span><br></pre></td></tr></table></figure>

<ol start="3">
<li>更新npm</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -g npm</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>再次尝试安装看是否有效。</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/14/npm-ERR-code-EINTEGRITY/" data-id="cktcaskhw00373guc5ey7b5ds" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-iOS-面试题简要汇总" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/12/iOS-%E9%9D%A2%E8%AF%95%E9%A2%98%E7%AE%80%E8%A6%81%E6%B1%87%E6%80%BB/" class="article-date">
  <time datetime="2020-04-12T02:13:58.000Z" itemprop="datePublished">2020-04-12</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/iOS/">iOS</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/12/iOS-%E9%9D%A2%E8%AF%95%E9%A2%98%E7%AE%80%E8%A6%81%E6%B1%87%E6%80%BB/">iOS 面试题简要汇总</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="常见面试题的概要汇总"><a href="#常见面试题的概要汇总" class="headerlink" title="常见面试题的概要汇总"></a>常见面试题的概要汇总</h2><h3 id="代理为什么要用weak-delegate-和-DataSource-区别，block和delegate区别？"><a href="#代理为什么要用weak-delegate-和-DataSource-区别，block和delegate区别？" class="headerlink" title="代理为什么要用weak, delegate 和 DataSource 区别，block和delegate区别？"></a>代理为什么要用weak, delegate 和 DataSource 区别，block和delegate区别？</h3><ul>
<li>防止循环引用；</li>
<li>delegate主要是操作,dataSource主要是提供数据;</li>
<li>block方便引用上下文，代码更容易理解，轻量级，容易造成循环引用；delegate架构设计更清晰，用weak修饰不容易造成循环引用，没有block轻量级；</li>
</ul>
<h3 id="属性的实质是什么？包括哪几个部分？属性默认的关键字都有哪些？-dynamic关键字和-synthesize关键字是用来做什么的？"><a href="#属性的实质是什么？包括哪几个部分？属性默认的关键字都有哪些？-dynamic关键字和-synthesize关键字是用来做什么的？" class="headerlink" title="属性的实质是什么？包括哪几个部分？属性默认的关键字都有哪些？@dynamic关键字和@synthesize关键字是用来做什么的？"></a>属性的实质是什么？包括哪几个部分？属性默认的关键字都有哪些？@dynamic关键字和@synthesize关键字是用来做什么的？</h3><ul>
<li>属性本质是@property = ivar + get + set,即会自动生成get/set方法；</li>
<li>默认关键字有atomic\nonatomic@synthesize@dynamic\getter=getterName\setter=setterName\readwrite\readonly\assign\retian\copy\strong\weak等;</li>
<li>@dynamic,动态实现属性访问方法，需要再NSObject中实现 <code>+(BOOL)resolveInstanceMethod(SEL) sel</code> 方法中指定动态实现的函数或者方法，或者手动实现方法；</li>
<li>@Synthesize 自动实现get、set方法；</li>
</ul>
<h3 id="NSString为什么要用copy，如果用strong会有什么问题？"><a href="#NSString为什么要用copy，如果用strong会有什么问题？" class="headerlink" title="NSString为什么要用copy，如果用strong会有什么问题？"></a>NSString为什么要用copy，如果用strong会有什么问题？</h3><ul>
<li>NSString指向NSMUtableString时，如果用copy，则是深copy，strong 则是指向同一个对象，有可变的隐患；</li>
<li>不可变字符串则是一样效果；copy在这种情况下是浅copy；</li>
</ul>
<h3 id="copy、mutablecopy什么时候是深copy、浅copy，可变对象copy后有什么影响？"><a href="#copy、mutablecopy什么时候是深copy、浅copy，可变对象copy后有什么影响？" class="headerlink" title="copy、mutablecopy什么时候是深copy、浅copy，可变对象copy后有什么影响？"></a>copy、mutablecopy什么时候是深copy、浅copy，可变对象copy后有什么影响？</h3><ul>
<li>copy不可变对象浅copy，引用计数+1，copy可变对象深copy；</li>
<li>mutablecopy全部是深copy；</li>
<li>mutable对象copy后变不可变对象,所以NSMutableString不可用copy修饰；</li>
<li>不可变对象mutablecopy后变为可变对象；</li>
<li>对数组深copy，数组中的对应依然是浅copy;可通过<code>initWithArray:copyItems:</code>或者归档解档实现(对多层嵌套依然有效)；</li>
</ul>
<h3 id="自定义对象如果实现copy、mutablecopy？"><a href="#自定义对象如果实现copy、mutablecopy？" class="headerlink" title="自定义对象如果实现copy、mutablecopy？"></a>自定义对象如果实现copy、mutablecopy？</h3><ul>
<li>实现nscopying和NSMutableCopying协议；</li>
</ul>
<h3 id="IBOutLet修饰的UIView也适用weak；"><a href="#IBOutLet修饰的UIView也适用weak；" class="headerlink" title="IBOutLet修饰的UIView也适用weak；"></a>IBOutLet修饰的UIView也适用weak；</h3><ul>
<li>因为视图view已经对子视图有强引用了；</li>
</ul>
<h3 id="nonatomic-atomic区别；atomic是绝对的线程安全吗，如果不是如何实现；"><a href="#nonatomic-atomic区别；atomic是绝对的线程安全吗，如果不是如何实现；" class="headerlink" title="nonatomic atomic区别；atomic是绝对的线程安全吗，如果不是如何实现；"></a>nonatomic atomic区别；atomic是绝对的线程安全吗，如果不是如何实现；</h3><ul>
<li>atomic 保障了get、set方法的完整性；</li>
<li>atomic 不是绝对的线程安全，set同时其他线程可以get；如果要线程安全可以使用线程锁；</li>
</ul>
<h3 id="UICollectionView如何实现自定义？"><a href="#UICollectionView如何实现自定义？" class="headerlink" title="UICollectionView如何实现自定义？"></a>UICollectionView如何实现自定义？</h3><ul>
<li>UICollectionViewLayoutAttributes,UICollectionFlowLayout;</li>
</ul>
<h3 id="StoryBoard开发界面有什么弊端，如何避免；"><a href="#StoryBoard开发界面有什么弊端，如何避免；" class="headerlink" title="StoryBoard开发界面有什么弊端，如何避免；"></a>StoryBoard开发界面有什么弊端，如何避免；</h3><ul>
<li>难以维护，比如全局改动一个字体；</li>
<li>storyBoard过大的话，加载速度慢；</li>
<li>遇到错误，提示不明显；</li>
<li>动态修改属性通过代码实现；</li>
<li>部分可以独立的view 可使用xib；</li>
</ul>
<h3 id="进程与线程、同步与异步、并行与并发还有穿行；"><a href="#进程与线程、同步与异步、并行与并发还有穿行；" class="headerlink" title="进程与线程、同步与异步、并行与并发还有穿行；"></a>进程与线程、同步与异步、并行与并发还有穿行；</h3><ul>
<li>进程是系统内的一个运行的程序，比如一个运行的exe就是一个进程；线程是进程中的一个执行流程；</li>
<li>同步是顺序执行，执行完成一个在执行下个任务，需要等待，派发任务时需要任务执行完；</li>
<li>异步是彼此任务独立，在等待某事件的过程中继续做自己的事，不需要等待这些事件完成后再工作，派发任务不会立即执行；</li>
<li>并发是一个cpu多个任务复用，轮番执行任务，多个任务共享，提高效率；</li>
<li>并行是多个cpu同时处理多个任务；</li>
<li>穿行就是任务顺序执行；</li>
</ul>
<h2 id="线程间通信；"><a href="#线程间通信；" class="headerlink" title="线程间通信；"></a>线程间通信；</h2><ul>
<li>NSThread</li>
<li>GCD</li>
<li>NSOperation</li>
</ul>
<h3 id="GCD中常用函数"><a href="#GCD中常用函数" class="headerlink" title="GCD中常用函数"></a>GCD中常用函数</h3><ul>
<li>延迟派发dispatch_after()</li>
<li>一次性执行 dispatch_once()</li>
<li>栅栏函数 dispatch_barrier_async/dispatch_barrier_sync</li>
<li>队列组 dispatch_group</li>
<li>GCD 定时器 并且更加精确</li>
</ul>
<h3 id="如何使用队列来避免资源抢夺？"><a href="#如何使用队列来避免资源抢夺？" class="headerlink" title="如何使用队列来避免资源抢夺？"></a>如何使用队列来避免资源抢夺？</h3><ul>
<li>dispatch_barrier_async,等前面队列完成后再进行操作；</li>
</ul>
<h3 id="数据持久化方案"><a href="#数据持久化方案" class="headerlink" title="数据持久化方案"></a>数据持久化方案</h3><ul>
<li>coreData realm fmdb</li>
</ul>
<h3 id="Appdelegate-方法，第一次启动调用方法，从前台到后台调用方法；"><a href="#Appdelegate-方法，第一次启动调用方法，从前台到后台调用方法；" class="headerlink" title="Appdelegate 方法，第一次启动调用方法，从前台到后台调用方法；"></a>Appdelegate 方法，第一次启动调用方法，从前台到后台调用方法；</h3><ul>
<li>第一次调用的方法是</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions</span><br></pre></td></tr></table></figure>

<ul>
<li>前台到后台调用方法</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)applicationWillResignActive:(UIApplication *)application <span class="comment">//将要进入后台</span></span><br><span class="line">- (<span class="keyword">void</span>)applicationDidEnterBackground:(UIApplication *)application<span class="comment">//已经进入后台</span></span><br><span class="line">- (<span class="keyword">void</span>)applicationWillEnterForeground:(UIApplication *)application<span class="comment">//将要进入前台</span></span><br><span class="line"> - (<span class="keyword">void</span>)applicationDidBecomeActive:(UIApplication *)application<span class="comment">//已经进入前台</span></span><br><span class="line"> - (<span class="keyword">void</span>)applicationWillTerminate:(UIApplication *)application<span class="comment">//程序结束</span></span><br></pre></td></tr></table></figure>


<h3 id="NSCache哪些地方优与NSDictionary"><a href="#NSCache哪些地方优与NSDictionary" class="headerlink" title="NSCache哪些地方优与NSDictionary"></a>NSCache哪些地方优与NSDictionary</h3><ul>
<li>都是类似的key-value存储，不同的是nscache的key不用实现copying协议，value也不用实现coding协议；</li>
</ul>
<h3 id="知不知道Designated-Initializer（指定初始化函数）？使用它的时候有什么需要注意的问题？"><a href="#知不知道Designated-Initializer（指定初始化函数）？使用它的时候有什么需要注意的问题？" class="headerlink" title="知不知道Designated Initializer（指定初始化函数）？使用它的时候有什么需要注意的问题？"></a>知不知道Designated Initializer（指定初始化函数）？使用它的时候有什么需要注意的问题？</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER;</span><br><span class="line">- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;</span><br></pre></td></tr></table></figure>

<h3 id="description"><a href="#description" class="headerlink" title="description"></a>description</h3><ul>
<li>nslog</li>
<li>默认是NSObject的实现，内存地址，类名等；</li>
<li>可以覆盖后输出关键信息，方便调试；</li>
</ul>
<h3 id="OC使用哪种机制管理内存"><a href="#OC使用哪种机制管理内存" class="headerlink" title="OC使用哪种机制管理内存"></a>OC使用哪种机制管理内存</h3><ul>
<li>returnCount机制，每次runloop的时候都要检查对象的returnCount是否小于等于0，则释放；</li>
<li>对比java的引用机制，通过内存回收机制遍历不可达的回收；</li>
<li>引用计数效率更高，但是容易出现循环引用；</li>
</ul>
<h3 id="block实质，几种block"><a href="#block实质，几种block" class="headerlink" title="block实质，几种block"></a>block实质，几种block</h3><ul>
<li>block 结构体，有isa指针指向自己的类（global malloc stack），desc结构体描述bock，_frowording指向自己活着堆上自己的地址，截取上下文的变量，函数指针指向block代码块</li>
<li>block 编译的时候会生成一个函数，第一参数是block结构体指针，执行block相当于执行block里面_frowding里面的函数</li>
</ul>
<h3 id="static-inline-是什么？"><a href="#static-inline-是什么？" class="headerlink" title="static inline 是什么？"></a>static inline 是什么？</h3><ul>
<li>tatic inline内联函数：使用它可以减少函数运行时间，提高程序运行速度。但内联函数里不能写循环，开关语句，而且最好不写过于冗长的函数。</li>
</ul>
<h3 id="属性的默认关键字是什么？"><a href="#属性的默认关键字是什么？" class="headerlink" title="属性的默认关键字是什么？"></a>属性的默认关键字是什么？</h3><ul>
<li>在声明property时，如果不指定关键字，编译器会为property生成默认的关键字。</li>
<li>对应基本数据类型，默认关键字为atomic，assign，readwrite。</li>
<li>对应对象类型，默认关键字为atomic，strong，readwrite。</li>
</ul>
<h3 id="为什么在默认情况下无法修改被block捕获的变量？-block都做了什么？"><a href="#为什么在默认情况下无法修改被block捕获的变量？-block都做了什么？" class="headerlink" title="为什么在默认情况下无法修改被block捕获的变量？__block都做了什么？"></a>为什么在默认情况下无法修改被block捕获的变量？__block都做了什么？</h3><ul>
<li>在block中访问的外部变量是复制过去的，写操作不对原变量生效。</li>
</ul>
<h3 id="模拟一下循环引用的一个情况？block实现界面反向传值该怎么做？"><a href="#模拟一下循环引用的一个情况？block实现界面反向传值该怎么做？" class="headerlink" title="模拟一下循环引用的一个情况？block实现界面反向传值该怎么做？"></a>模拟一下循环引用的一个情况？block实现界面反向传值该怎么做？</h3><ul>
<li>两个.h文件互相import了对方造成循环引用。</li>
<li>B反向往A传值，首先在A中声明Block</li>
<li>在B中添加属性，@property (nonatomic,copy) MyBlock block;</li>
<li>在准备接收值的A控制器里实现block，B.block = ^void(NSString *name){_label.text = name;};</li>
<li>谁要传值就在B那里调用self.block(var);。</li>
</ul>
<h3 id="iOS事件传递响应链是什么？"><a href="#iOS事件传递响应链是什么？" class="headerlink" title="iOS事件传递响应链是什么？"></a>iOS事件传递响应链是什么？</h3><p>在我们点击屏幕的时候，iphone OS获取到了用户进行了“单击”这一行为，操作系统把包含这些点击事件的信息包装成UITouch和UIEvent形式的实例，然后找到当前运行的程序，逐级寻找能够响应这个事件的对象，直到没有响应者响应。这一寻找的过程，被称作事件的响应链。不同的响应者以链式方式寻找，AppDelegate-&gt;UIApplication-&gt;UIWindow-&gt;UIViewController-&gt;UIView-&gt;UIButton</p>
<h3 id="利用kvo数据绑定，在mvvm模式中，数据绑定被用的很广泛，能够动态的根据数据改变刷新UI。"><a href="#利用kvo数据绑定，在mvvm模式中，数据绑定被用的很广泛，能够动态的根据数据改变刷新UI。" class="headerlink" title="利用kvo数据绑定，在mvvm模式中，数据绑定被用的很广泛，能够动态的根据数据改变刷新UI。"></a>利用kvo数据绑定，在mvvm模式中，数据绑定被用的很广泛，能够动态的根据数据改变刷新UI。</h3><h3 id="多线程锁"><a href="#多线程锁" class="headerlink" title="多线程锁"></a>多线程锁</h3><h3 id="strong-weak-assign-的区别"><a href="#strong-weak-assign-的区别" class="headerlink" title="strong weak assign 的区别"></a>strong weak assign 的区别</h3><h3 id="类和结构体的区别"><a href="#类和结构体的区别" class="headerlink" title="类和结构体的区别"></a>类和结构体的区别</h3><h3 id="多线程锁-1"><a href="#多线程锁-1" class="headerlink" title="多线程锁"></a>多线程锁</h3><h3 id="strong-weak-assign-区别"><a href="#strong-weak-assign-区别" class="headerlink" title="strong weak assign 区别"></a>strong weak assign 区别</h3><h3 id="oc-和-swift-混编"><a href="#oc-和-swift-混编" class="headerlink" title="oc 和 swift 混编"></a>oc 和 swift 混编</h3><h3 id="mrc-和-arc-混编"><a href="#mrc-和-arc-混编" class="headerlink" title="mrc 和 arc 混编"></a>mrc 和 arc 混编</h3><h3 id="http-和-tcp-区别"><a href="#http-和-tcp-区别" class="headerlink" title="http 和 tcp 区别"></a>http 和 tcp 区别</h3><h3 id="进程间的通信方式有哪些"><a href="#进程间的通信方式有哪些" class="headerlink" title="进程间的通信方式有哪些"></a>进程间的通信方式有哪些</h3><ol>
<li>URL Scheme</li>
<li>Keychain</li>
<li>UIPasteboard</li>
<li>UIDocumentInteractionController</li>
<li>Local socket</li>
<li>AirDrop</li>
<li>UIActivityViewController</li>
<li>App Groups</li>
</ol>
<h3 id="oc-对象-是结构体还是联合体"><a href="#oc-对象-是结构体还是联合体" class="headerlink" title="oc 对象 是结构体还是联合体"></a>oc 对象 是结构体还是联合体</h3><h3 id="多态"><a href="#多态" class="headerlink" title="多态"></a>多态</h3><ul>
<li>不同对象以自己的方式响应相同的消息的能力叫做多态。</li>
<li>OC中通过继承、select名字、参数等可实现；</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/12/iOS-%E9%9D%A2%E8%AF%95%E9%A2%98%E7%AE%80%E8%A6%81%E6%B1%87%E6%80%BB/" data-id="cktcaskho00263guce302cmke" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/iOS/" rel="tag">iOS</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E9%9D%A2%E8%AF%95/" rel="tag">面试</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-flutter-0基础快速学习路线" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/08/flutter-0%E5%9F%BA%E7%A1%80%E5%BF%AB%E9%80%9F%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/" class="article-date">
  <time datetime="2020-04-08T02:57:21.000Z" itemprop="datePublished">2020-04-08</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/flutter/">flutter</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/08/flutter-0%E5%9F%BA%E7%A1%80%E5%BF%AB%E9%80%9F%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/">flutter 0基础快速学习路线</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="基础学习"><a href="#基础学习" class="headerlink" title="基础学习"></a>基础学习</h2><ul>
<li><input checked="" disabled="" type="checkbox"> 搭建flutter开发环境，参考<a href="https://flutterchina.club/setup-macos/" target="_blank" rel="noopener">https://flutterchina.club/setup-macos/</a>，安装默认项目到模拟器或者真机；</li>
<li><input disabled="" type="checkbox"> 通读Dort语法一遍<a href="https://juejin.im/post/5c52a386f265da2de25b5c36" target="_blank" rel="noopener">https://juejin.im/post/5c52a386f265da2de25b5c36</a>,将文章中的语法敲一遍；</li>
<li><input checked="" disabled="" type="checkbox"> 实现一个简单的HelloWorld页面，目的是熟悉Flutter的项目结构和StatelessWidget组件，通读Flutter的所有UI组件一遍：<a href="https://juejin.im/post/5c18d181f265da611f07a128" target="_blank" rel="noopener">https://juejin.im/post/5c18d181f265da611f07a128</a>，要求记住flutter的常用UI组件的继承关系；</li>
<li><input disabled="" type="checkbox"> 实现页面跳转、传参、接收返回值，目的是熟悉Navigator组件；</li>
<li><input disabled="" type="checkbox"> 实现一个淘宝-个人中心页面，暂不要求交互，但是页面的样式要大致实现，主要目的是熟悉基本UI组件，尤其是布局、文本、图片；</li>
<li><input disabled="" type="checkbox"> 实现一个淘宝-首页，要求包含交互：下拉刷新和上拉加载更多，主要目的是熟悉复杂列表视图、滚动嵌套、手势；</li>
<li><input disabled="" type="checkbox"> 实现一个简单登录页面的Http请求，服务端自己写，主要目的是熟悉Flutter的输入框、Dart的异步编程(async/await/Future)、网络请求、json解析、响应式编程(StatefulWidget/setState)；</li>
<li><input disabled="" type="checkbox"> 实现一个简单登录页面的grpc请求，protobuf文件和服务端也自己写，主要目的是熟悉grpc插件的用法；</li>
<li><input disabled="" type="checkbox"> 实现读取SP的简单页面，不准用第三方插件，自己用MethodChannel实现Flutter调用原生的功能；</li>
<li><input disabled="" type="checkbox"> 实现Flutter项目接入宿主Android容器，主要目的是熟悉Flutter静态路由和Android原生传参给FlutterView。</li>
</ul>
<h2 id="进阶阶段"><a href="#进阶阶段" class="headerlink" title="进阶阶段"></a>进阶阶段</h2><blockquote>
<p>调研必须有输出，实践性的要有代码产出，理论性的要有wiki产出，没有产出的调研，就是耍流氓。</p>
</blockquote>
<ul>
<li><input disabled="" type="checkbox"> 写一个国际化的demo，实现多语言切换；</li>
<li><input disabled="" type="checkbox"> 写一个自定义View的Demo，熟悉绘图三剑客：canvas、path、paint；</li>
<li><input disabled="" type="checkbox"> 写一个网络图片缓存的demo，并了解其实现原理和内存占用；</li>
<li><input disabled="" type="checkbox"> 阅读源码，了解Flutter的渲染机制，如何从Widget-&gt;Element-&gt;RenderObject；</li>
<li><input disabled="" type="checkbox"> 了解Dart的异步机制，深入理解async/await/Future的原理。</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/08/flutter-0%E5%9F%BA%E7%A1%80%E5%BF%AB%E9%80%9F%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/" data-id="cktcaskhi001m3guc27319a6h" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/flutter/" rel="tag">flutter</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="历时4天完成wanandroid-Flutter初版" class="article article-type-历时4天完成wanandroid" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/03/Flutter%E5%88%9D%E7%89%88/" class="article-date">
  <time datetime="2020-04-03T04:42:30.000Z" itemprop="datePublished">2020-04-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/03/Flutter%E5%88%9D%E7%89%88/">Flutter初版</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        
      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/03/Flutter%E5%88%9D%E7%89%88/" data-id="cktcaskgo00043guc3eoda4fx" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-Keyboard-Maestro-Mac-键盘效率工具" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/03/Keyboard-Maestro-Mac-%E9%94%AE%E7%9B%98%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/" class="article-date">
  <time datetime="2020-04-03T02:41:12.000Z" itemprop="datePublished">2020-04-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/03/Keyboard-Maestro-Mac-%E9%94%AE%E7%9B%98%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/">Keyboard Maestro Mac 键盘效率工具</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        
      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/03/Keyboard-Maestro-Mac-%E9%94%AE%E7%9B%98%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/" data-id="cktcaskh0000d3gucbya62504" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-flutter常见错误汇总" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/04/02/flutter%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E6%B1%87%E6%80%BB/" class="article-date">
  <time datetime="2020-04-02T04:58:49.000Z" itemprop="datePublished">2020-04-02</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/flutter/">flutter</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/04/02/flutter%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E6%B1%87%E6%80%BB/">flutter常见错误汇总</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="iOS真机调试证书错误"><a href="#iOS真机调试证书错误" class="headerlink" title="iOS真机调试证书错误"></a>iOS真机调试证书错误</h2><p><img src="ios_appid.png" alt="证书错误"></p>
<p>iOS真机调试中需要配置证书，现在苹果允许个人免费账号真机调试，只要要apple id就行。Flutter项目运行到iOS真机上如果没有配置证书或者原始证书配置有问题，就会报错如上图，如何修改呢，需要用到Xcode。</p>
<p>用Xcode打开项目，检查证书配置是否有问题:</p>
<p><img src="ios_develop_team.png" alt="配置证书"></p>
<h2 id="mac-10-15-运行程序提示“软件已损坏或无法验证等错误”"><a href="#mac-10-15-运行程序提示“软件已损坏或无法验证等错误”" class="headerlink" title="mac 10.15 运行程序提示“软件已损坏或无法验证等错误”"></a>mac 10.15 运行程序提示“软件已损坏或无法验证等错误”</h2><p>运行如下命令:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">sudo spctl --master-disable</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/libimobiledevice/idevice_id</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/libimobiledevice/idevicename</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/libimobiledevice/idevicescreenshot</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/libimobiledevice/idevicesyslog</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/libimobiledevice/ideviceinfo</span><br><span class="line">xattr -r -d com.apple.quarantine ~/development/flutter/bin/cache/artifacts/usbmuxd/iproxy</span><br></pre></td></tr></table></figure>

<p>如果还有其它软件还有如此提示可以参考上面命令，另外第一个命令其实修改了软件修改条件，在设置-&gt;安全中可以看到,如果担心安全问题可以修改回去，下次需要再设置。</p>
<p><img src="mac_security.png" alt="mac设置"></p>
<h2 id="Android-Studio-运行后无法热加载"><a href="#Android-Studio-运行后无法热加载" class="headerlink" title="Android Studio 运行后无法热加载"></a>Android Studio 运行后无法热加载</h2><p>错误提示如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Error connecting to the service protocol: failed to <span class="built_in">connect</span> to http:<span class="comment">//127.0.0.1</span></span><br></pre></td></tr></table></figure>

<p>一般是设备版本的问题，建议换个设备或者模拟器试试。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://bianchengme.gitee.io/2020/04/02/flutter%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E6%B1%87%E6%80%BB/" data-id="cktcaskhl001v3gucfjla8d44" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/BUG/" rel="tag">BUG</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/flutter/" rel="tag">flutter</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/iOS%E7%9C%9F%E6%9C%BA%E8%BF%90%E8%A1%8C/" rel="tag">iOS真机运行</a></li></ul>

    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/3/">&amp;laquo; Prev</a><a class="page-number" href="/">1</a><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><a class="page-number" href="/page/6/">6</a><a class="extend next" rel="next" href="/page/5/">Next &amp;raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Docker/">Docker</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/Docker/Nacos/">Nacos</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Docker/mysql/">mysql</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA/">JAVA</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA/JVM/">JVM</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Markdown/">Markdown</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Windows/">Windows</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/docker/">docker</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/docker/redis/">redis</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/flutter/">flutter</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/git/">git</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/iOS/">iOS</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/iOS/Objective-C/">Objective-C</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/iOS/Xcode/">Xcode</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/java/">java</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/java/%E5%A4%9A%E7%BA%BF%E7%A8%8B/">多线程</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/mysql/">mysql</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/vue/">vue</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/BUG/" rel="tag">BUG</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Docker/" rel="tag">Docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JAVA/" rel="tag">JAVA</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JVM/" rel="tag">JVM</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Markdown/" rel="tag">Markdown</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Objective-C/" rel="tag">Objective-C</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/RunTime/" rel="tag">RunTime</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Swift/" rel="tag">Swift</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/UI/" rel="tag">UI</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Windows/" rel="tag">Windows</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Xcode/" rel="tag">Xcode</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/docker/" rel="tag">docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/flutter/" rel="tag">flutter</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/" rel="tag">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/hook/" rel="tag">hook</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/iOS/" rel="tag">iOS</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/iOS%E7%9C%9F%E6%9C%BA%E8%BF%90%E8%A1%8C/" rel="tag">iOS真机运行</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java/" rel="tag">java</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mysl/" rel="tag">mysl</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mysql/" rel="tag">mysql</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/nacos/" rel="tag">nacos</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/volatile/" rel="tag">volatile</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vue/" rel="tag">vue</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E4%BC%98%E5%8C%96/" rel="tag">优化</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" rel="tag">多线程</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/" rel="tag">学习计划</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%B7%A5%E5%85%B7/" rel="tag">工具</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/" rel="tag">并发编程</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%AE%97%E6%B3%95/" rel="tag">算法</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%BD%91%E7%BB%9C/" rel="tag">网络</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%83%A8%E7%BD%B2/" rel="tag">部署</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9D%A2%E8%AF%95/" rel="tag">面试</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/BUG/" style="font-size: 10px;">BUG</a> <a href="/tags/Docker/" style="font-size: 10px;">Docker</a> <a href="/tags/JAVA/" style="font-size: 10px;">JAVA</a> <a href="/tags/JVM/" style="font-size: 10px;">JVM</a> <a href="/tags/Markdown/" style="font-size: 10px;">Markdown</a> <a href="/tags/Objective-C/" style="font-size: 16.67px;">Objective-C</a> <a href="/tags/RunTime/" style="font-size: 10px;">RunTime</a> <a href="/tags/Swift/" style="font-size: 10px;">Swift</a> <a href="/tags/UI/" style="font-size: 13.33px;">UI</a> <a href="/tags/Windows/" style="font-size: 10px;">Windows</a> <a href="/tags/Xcode/" style="font-size: 10px;">Xcode</a> <a href="/tags/docker/" style="font-size: 13.33px;">docker</a> <a href="/tags/flutter/" style="font-size: 13.33px;">flutter</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/hook/" style="font-size: 10px;">hook</a> <a href="/tags/iOS/" style="font-size: 20px;">iOS</a> <a href="/tags/iOS%E7%9C%9F%E6%9C%BA%E8%BF%90%E8%A1%8C/" style="font-size: 10px;">iOS真机运行</a> <a href="/tags/java/" style="font-size: 16.67px;">java</a> <a href="/tags/mysl/" style="font-size: 10px;">mysl</a> <a href="/tags/mysql/" style="font-size: 10px;">mysql</a> <a href="/tags/nacos/" style="font-size: 10px;">nacos</a> <a href="/tags/redis/" style="font-size: 10px;">redis</a> <a href="/tags/volatile/" style="font-size: 10px;">volatile</a> <a href="/tags/vue/" style="font-size: 10px;">vue</a> <a href="/tags/%E4%BC%98%E5%8C%96/" style="font-size: 10px;">优化</a> <a href="/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" style="font-size: 10px;">多线程</a> <a href="/tags/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/" style="font-size: 10px;">学习计划</a> <a href="/tags/%E5%B7%A5%E5%85%B7/" style="font-size: 10px;">工具</a> <a href="/tags/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/" style="font-size: 10px;">并发编程</a> <a href="/tags/%E7%AE%97%E6%B3%95/" style="font-size: 10px;">算法</a> <a href="/tags/%E7%BD%91%E7%BB%9C/" style="font-size: 10px;">网络</a> <a href="/tags/%E9%83%A8%E7%BD%B2/" style="font-size: 10px;">部署</a> <a href="/tags/%E9%9D%A2%E8%AF%95/" style="font-size: 10px;">面试</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/09/">September 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/06/">June 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/05/">May 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">March 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/10/">October 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/09/">September 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/08/">August 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/07/">July 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/05/">May 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/04/">April 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/03/">March 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/05/">May 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/03/">March 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/02/">February 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/10/">October 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/09/07/JVM-%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90%E4%BC%98%E5%8C%96/">JVM 逃逸分析优化</a>
          </li>
        
          <li>
            <a href="/2021/07/02/Nacos%E9%80%9A%E8%BF%87Docke%E9%83%A8%E7%BD%B2/">Nacos通过Docke部署</a>
          </li>
        
          <li>
            <a href="/2021/07/01/Docker%E5%AE%89%E8%A3%85mysql5-7/">Docker安装mysql5.7</a>
          </li>
        
          <li>
            <a href="/2021/07/01/Docker%E5%AE%89%E8%A3%85redis/">Docker安装redis</a>
          </li>
        
          <li>
            <a href="/2021/06/30/Java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B-volatile%E5%85%B3%E9%94%AE%E5%AD%97%E7%90%86%E8%A7%A3/">Java并发编程-volatile关键字理解</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2021 jmme@foxmail.com<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>




  </div>
</body>
</html>